package com.kasax.plugin.app.visitor.lifecycle3

import com.kasax.plugin.app.LogUtils
import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.Opcodes
import org.objectweb.asm.Type
import org.objectweb.asm.commons.LocalVariablesSorter

class NewLifecycleMethodVisitor extends LocalVariablesSorter {
    private String TAG = "NewLifecycleMethodVisitor"
    private String methodName
    private String className
    private int startTimeVar

    NewLifecycleMethodVisitor(MethodVisitor mv, int access, String name, String descriptor, String className) {
        super(Opcodes.ASM7, access, descriptor, mv)
        this.methodName = name
        this.className = className
    }


    @Override
    void visitCode() {
        super.visitCode()
        LogUtils.d(TAG, "visitCode cls-name: $className , method-name: $methodName start...")
        // 插入开始时间记录
        // 静态方法调用
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", "currentTimeMillis", "()J", false)
        // 分配 long 类型的局部变量
        startTimeVar = newLocal(Type.LONG_TYPE)
        mv.visitVarInsn(Opcodes.LSTORE, startTimeVar)
        // 添加方法进入标记
        mv.visitLdcInsn(className)
        mv.visitLdcInsn(methodName)
        mv.visitMethodInsn(Opcodes.INVOKESTATIC,
                "com/kasax/basiclib/LifecycleTracer",
                "onMethodStart",
                "(Ljava/lang/String;Ljava/lang/String;)V",
                false
        )
        LogUtils.d(TAG, "visitCode cls-name: $className , method-name: $methodName complete...")
    }

    @Override
    void visitInsn(int opcode) {
        LogUtils.d(TAG, "visitInsn cls-name: $className , method-name: $methodName start...")
        // 在return指令前插入耗时计算
        if (opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) {
            insertTimeCostCalculation();
        }
        LogUtils.d(TAG, "visitInsn cls-name: $className , method-name: $methodName complete...")
        super.visitInsn(opcode)
    }

    private void insertTimeCostCalculation() {
        // 计算耗时并记录
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", "currentTimeMillis", "()J", false);
        mv.visitVarInsn(Opcodes.LLOAD, startTimeVar);
        mv.visitInsn(Opcodes.LSUB);

        // 确保栈顶是 long 类型，避免类型冲突
        mv.visitLdcInsn(className);
        mv.visitLdcInsn(methodName);
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/kasax/basiclib/LifecycleTracer", "recordCost",
                "(JLjava/lang/String;Ljava/lang/String;)V", false);
    }

}